home *** CD-ROM | disk | FTP | other *** search
- /**
- -- graphics shell.c
- --
- -- This file is a shell that can be used to build QuickDraw GX graphics applications.
- -- It contains all of the required calls to use the "new" QuickDraw GX routines and
- -- QuickDraw (i.e. windows) together. It will put up one window. You "quit"
- -- the application by clicking in the close box. This shell does not use a menu.
- --
- -- The application is expected to supply the following functions which are called
- -- by this shell:
- --
- -- void DoInitialization(WindowPtr);
- -- void DoDraw(WindowPtr);
- -- void DoDispose(WindowPtr);
- -- void DoClick(gxPoint, WindowPtr);
- -- void DoIdle(WindowPtr);
- --
- --
- -- Change History:
- --
- -- 4/94 - Added the gxPoint as a parameter to the DoClick( gxPoint mouseLoc, WindowPtr myWindow )
- -- function to support hit testing. PLA
- --
- -- 3/94 - Removed the following varaibles: gDebugging & gGiveMeValidation see the comments
- -- for details (below).
- --
- -- - Added a Gestalt check to see if GX has been installed. Added extensive error
- -- checking to make sure the GX graphics client has been created and the GX heap
- -- correctly allocated. This shell will shut down at start-up and alert the user
- -- to the problem and bail if: GX is not installed, we cannot create the graphics
- -- client, or create a GX heap. PLA
- --
- -- 12/93 Updated the comment above the GXNewGraphicsCLient call to reflect the new fucntionality
- -- of this call in ß3. I also removed the work around with GXConvertQDPoint (..) where
- -- the call would not survive validation under ß2. Under ß3 the call suceeds when validation
- -- is set. PLA
- --
- -- 8/93 - Updated this file to run with the QD GX ß2 "GX-ified" interfaces
- -- - worked around a problem with GXConvertQDPoint (..) see the comments within
- -- the GetWindowBoundsShape (..) call for details (below). PLA
- --
- -- 6/92 Made the following variables global: gDebugging, gGiveMeValidation,gGraphicsHeapSize.
- -- See the comments for detail in this file. PLA
- --
- -- 6/91 Updated the shell to reflect the changes in "Graphics" v1.0d21.2. PLA
- --
- -- 3/90 New - PLA
- --
- --
- -- © Apple Computer, Inc. 1990 - 1994 All rights reserved
- --
- **/
-
-
- #include <Desk.h>
- #include <Events.h>
- #include <Fonts.h>
- #include <Windows.h>
- #include <Memory.h>
- #include <ToolUtils.h>
- #include <Quickdraw.h>
- #include <GestaltEqu.h>
-
- #include <GXEnvironment.h>
- #include <GXGraphics.h>
- #include <GXEnvironment.h>
- #include <GXErrors.h>
- #include "GraphicsLibraries.h"
-
- #include "graphics shell.h"
-
- #define kOSEvent app4Evt // event used by MultiFinder
- #define kSuspendResumeMessage 1 // high byte of suspend/resume event message
- #define kResumeMask 1 // bit of message field for resume vs. suspend
-
-
- #if defined(powerc) || defined(__powerc)
- QDGlobals qd;
- #endif
-
-
- WindowPtr gWindow, whichWindow;
-
- EventRecord gtheEvent;
- gxShape gWindowBoundsShape;
- gxViewPort gTheWindowsViewPort;
-
- /**------ Function Prototypes -----**/
- void main(void);
- gxShape GetWindowBoundsShape(void);
- Boolean EventLoop(void);
- void SetUpGXDebuggingWorld (Boolean GXDebuggingInstalled);
-
- /*------ main -----------------------------------------------------------------------------------------*/
-
- void main()
- {
- CursHandle theCurs;
- long theFeature;
- Boolean debuggingInitInstalled = false;
-
- //
- // Generic heap initialization.
- //
- MaxApplZone();
- MoreMasters(); MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters(); MoreMasters();
-
- //
- // Initialize the toolbox
- //
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitCursor();
-
- theCurs = GetCursor(watchCursor);
- SetCursor(*theCurs);
-
- //
- // Check to see if QuickDraw GX is installed. If not, alert the user...
- //
- if ( (Gestalt(gestaltGraphicsVersion, &theFeature) == noErr) )
- {
- gxGraphicsClient newClient;
-
- //
- // The GX gestaltGraphicsAttr Gestalt attribute can be used to determine if:
- // the graphics piece of GX has been loaded, the GX debugging init is installed, or
- // your are running the PowerPC version.
- //
- // In our case, we only need to know if the debugging init was installed. If it is,
- // we will enable the GX validation and notice handling features.We define
- // debuggingInitInstalled as true to enable GX validation and notice handler
- // within the SetUpGXDebuggingWorld function.
- //
- if ( (Gestalt(gestaltGraphicsAttr, &theFeature) == noErr) )
- if ( (theFeature & gestaltGraphicsIsDebugging) == gestaltGraphicsIsDebugging )
- debuggingInitInstalled = true;
-
-
- newClient = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
-
- //
- // After we attempted to create the graphics client, we need to determine if the call
- // succeeded. If the call did not (as in the case for all GX functions), "newClient" will
- // be nil. If it is, we alert the user to the problem. Otherwise, we will attempted to
- // allocate the GX heap below...
- //
- if ( newClient )
- {
- //
- // Initialize the new graphics environment and create the GX heap.
- //
- GXEnterGraphics();
-
- //
- // Calling GXEnterGraphics allocates the memory within the GX heap. The only reason the
- // call would not succeed is if there is not enough memory. In this case, the graphics
- // error which will be posted is -27999 (out of memory). At this point, we have not
- // installed an error handler, so we check for the error number corresponding to the
- // out of memory error.
- //
- if ( GXGetGraphicsError( nil ) != -27999 )
- {
- SetUpGXDebuggingWorld (debuggingInitInstalled);
-
- //
- // Create a window and attach a GX viewPort to it. By attaching the viewPort to
- // the window will make sure that when a user moves or resizes the window all of
- // the GX drawing will occur within window.
- //
- // By the way, you cannot directly manipulate the parent viewPort attached to the
- // window, you will recieve a graphics error. This viewPort can only be manipulated
- // by the GX system. If you want to manipulate a viewPort attached to a window, it
- // _must_ be a child viewPort attached to the the parent viewPort attached to the
- // window.
- //
- gWindow = NewWindow(nil, &gWindowQDRect, gWindowTitle, true, noGrowDocProc,
- (WindowPtr)-1L, true, 0L);
-
- gTheWindowsViewPort = GXNewWindowViewPort(gWindow);
-
- GXIgnoreGraphicsNotice(transform_already_set);
- SetDefaultViewPort(gTheWindowsViewPort);
- GXPopGraphicsNotice();
-
- //
- // Get the global bounds of the window.
- //
- gWindowBoundsShape = GetWindowBoundsShape();
-
- //
- // Create the GX shapes we are going to draw to the window.
- //
- DoInitialization(gWindow);
-
- SetCursor(&qd.arrow);
-
- while (EventLoop())
- DoIdle(gWindow); // loop until the window is closed
-
- DoDispose(gWindow);
-
- GXExitGraphics(); // Deallocate all of the default structures
- GXDisposeGraphicsClient(newClient);
-
- } else {
- //
- // Since, we can not allocate the requested size for our GX heap, we need to throw
- // away the client we created and alert the user that there is not enough memory to
- // continue.
- //
- // However, you could try to create a smaller GX heap. If you decide to try to create
- // a smaller GX heap which would meet the needs of your application, you need to
- // dispose of the client you had originally created. Why? The original client
- // contains the GX heap size requested, which was too big, therefore you need to
- // dispose of it and create a client requesting a smaller size and call GXEnterGraphics
- // and check for an error.
- //
- GXDisposeGraphicsClient( newClient );
- DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
- }
- }
-
- } else DebugStr ("\p Unfortunately, you have not installed QuickDraw GX, I can't run without GX...");
-
- }
-
-
-
- /*------ SetUpGXDebuggingWorld ------------------------------------------------------------------------*/
- //
- // This function enables the GX error handling capabilities and validation routines. The validation
- // routines are only enabled, if the user has installed the QuickDraw GX debugging init. These routines
- // are not available with the non-debugging init. Calling them when they are not installed will not
- // cause any problems, but it will cause unnecessary work to be done by your application and the GX
- // dispatcher.
- //
- void SetUpGXDebuggingWorld (Boolean debuggingInitInstalled)
- {
- //
- // We set-up GX validation, if the user has installed the "GXGraphics (debug)" init (formerly
- // named "aSecretGraphics.debug). This validation setting is the reccommended setting while
- // you are developing your GX application. As you increase the amount of validation, the drawing
- // speed will SLOW down due to all of the internal checking.
- //
- // For additional details regarding the various levels of validation, please see the
- // QuickDraw GX : Environment & Utilities book.
- //
- if ( debuggingInitInstalled ) GXSetValidation(gxPublicValidation + gxTypeValidation);
-
- //
- // Calling SetGraphicsLibraryErrors will install a GX error and warning handler. This
- // call is provided by the QuickDraw GX "graphics debugging library". Any time a GX error
- // or warning is generated, it will be posted to Macsbug.
- //
- SetGraphicsLibraryErrors ();
-
- //
- // If the user has installed the GX debugging version, we install a notice handler. Why? The
- // GX notice handling capabilities are only available with the debugging version.
- //
- if ( debuggingInitInstalled ) SetGraphicsLibraryNotices();
- }
-
-
-
- /*------ GetWindowBoundsShape -------------------------------------------------------------------------*/
-
- gxShape GetWindowBoundsShape()
- {
- Rect theRect;
- Point QDtopLeft;
- Point QDbotRight;
- gxPoint QDGXtopLeft;
- gxPoint QDGXbotRight;
- gxRectangle theQDGXRect;
-
- //
- // The QuickDraw rect and points which represent the portRect of the window.
- //
- theRect = gWindow->portRect;
- QDtopLeft.h = theRect.left;
- QDtopLeft.v = theRect.top;
- QDbotRight.h = theRect.right;
- QDbotRight.v = theRect.bottom;
-
- //
- // Convert the global Quickdraw coordinates to local fixed coordinates.
- //
- GXConvertQDPoint(&QDtopLeft, 0, &QDGXtopLeft);
- GXConvertQDPoint(&QDbotRight, 0, &QDGXbotRight);
-
- //
- // Setup the dimensions for "gWindowBoundsShape"
- //
- theQDGXRect.top = QDGXtopLeft.y;
- theQDGXRect.left = QDGXtopLeft.x;
- theQDGXRect.bottom = QDGXbotRight.y;
- theQDGXRect.right = QDGXbotRight.x;
-
- return (GXNewRectangle(&theQDGXRect));
- }
-
-
-
- /*------ EventLoop ------------------------------------------------------------------------------------*/
-
- Boolean EventLoop()
- {
- static long sleep = 0;
-
- WaitNextEvent(everyEvent, >heEvent, sleep, nil);
-
- switch(gtheEvent.what)
- {
- case updateEvt:
- BeginUpdate((WindowPtr) gtheEvent.message);
- SetPort(gWindow);
- DoDraw(gWindow);
- EndUpdate((WindowPtr) gtheEvent.message);
- break;
-
- case mouseDown:
- switch (FindWindow(gtheEvent.where, &whichWindow)) {
- case inSysWindow:
- SystemClick(>heEvent, whichWindow);
- break;
-
- case inDrag:
- DragWindow(whichWindow, gtheEvent.where, &qd.screenBits.bounds);
- break;
-
- case inGoAway:
- if (TrackGoAway(whichWindow, gtheEvent.where))
- return false;
- break;
-
- case inContent:
- if (whichWindow != FrontWindow())
- SelectWindow(whichWindow);
- else
- {
- gxPoint mouseLoc;
- Point currMouseLoc;
-
- currMouseLoc.h = gtheEvent.where.h;
- currMouseLoc.v = gtheEvent.where.v;
-
- GXConvertQDPoint(&currMouseLoc, gTheWindowsViewPort, &mouseLoc);
-
- DoClick(mouseLoc, gWindow);
- }
- break;
-
- }
-
- case kOSEvent:
- switch ((unsigned long) gtheEvent.message >> 24) { // high byte of message
- case kSuspendResumeMessage: // suspend/resume is also an activate/deactivate
- if ((gtheEvent.message & kResumeMask) == 0)
- sleep = 80; // we are headed to the background, so slow down...
- else
- sleep = 0; // we are headed to the foreground, so speed up...
- break;
- }
- break;
- }
- return true;
- }
-
-